<template>
  <div class="banner-setting">
    <!-- 操控区 -->
    <div class="handler-box">
      <el-button
        type="primary"
        icon="el-icon-plus"
        size="small"
        @click="visible = true"
      >
        新增
      </el-button>

      <el-popconfirm
        title="确定要删除这些选中的数据吗？"
        @confirm="dobuleRemove"
      >
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="small"
          slot="reference"
        >
          批量删除
        </el-button>
      </el-popconfirm>
    </div>

    <!-- 表格区 -->
    <el-table
      :data="tableData"
      v-loading="tableLoading"
      height="100%"
      stripe
      @selection-change="selectionChange"
    >
      <el-table-column
        type="selection"
        min-width="5%"
        align="center"
      ></el-table-column>
      <el-table-column label="轮播图" min-width="15%">
        <template v-slot="{ row }">
          <el-image
            :src="row.carouselUrl"
            :preview-src-list="[row.carouselUrl]"
          ></el-image>
        </template>
      </el-table-column>
      <el-table-column
        label="跳转连接"
        min-width="30%"
        show-overflow-tooltip
        prop="redirectUrl"
      ></el-table-column>
      <el-table-column
        label="排序值"
        min-width="10%"
        align="center"
        prop="carouselRank"
      ></el-table-column>
      <el-table-column
        label="添加时间"
        min-width="20%"
        prop="createTime"
        :formatter="formatterTime"
      ></el-table-column>
      <el-table-column label="操作" min-width="20%">
        <template v-slot="{ row }">
          <el-link type="success" @click="triggerUpdate(row)">修改</el-link>

          <el-popconfirm
            title="确定要删除本条数据吗？"
            @confirm="singleRemove(row)"
          >
            <el-link type="primary" slot="reference">删除</el-link>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页区 -->
    <el-pagination
      background
      layout="sizes, prev, pager, next"
      :hide-on-single-page="true"
      :page-size.sync="pagination.pageSize"
      :total="pagination.total"
      :current-page.sync="pagination.pageNumber"
      @current-change="init"
      @size-change="init"
    ></el-pagination>

    <!-- 新增/修改 -->
    <el-dialog
      width="30%"
      :title="+ruleForm.carouselId === 0 ? `添加轮播图信息` : `修改轮播图信息`"
      :visible="visible"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :before-close="closeDialog"
    >
      <el-form
        label-width="100px"
        :model="ruleForm"
        :rules="rules"
        ref="formIns"
      >
        <el-form-item label="轮播图图片" prop="carouselUrl">
          <el-upload
            class="avatar-uploader"
            action="/api/upload/file"
            accept=".jpg,.jpeg,.png,.gif"
            :show-file-list="false"
            :multiple="false"
            :headers="headers"
            :on-success="uploadSuccess"
            :on-error="uploadError"
          >
            <img
              class="avatar-uploader-img"
              alt=""
              v-if="ruleForm.carouselUrl"
              :src="ruleForm.carouselUrl"
            />
            <i class="el-icon-plus avatar-uploader-icon" v-else></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="跳转连接" prop="redirectUrl">
          <el-input v-model.trim="ruleForm.redirectUrl"></el-input>
        </el-form-item>
        <el-form-item label="排序值" prop="carouselRank">
          <el-input-number
            v-model.trim="ruleForm.carouselRank"
          ></el-input-number>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button type="primary" :loading="confirmLoading" @click="submit">
          确认提交信息
        </el-button>
        <el-button @click="closeDialog">取消</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import _ from "@/assets/utils";

export default {
  name: "banner-setting",
  data() {
    // 校验地址
    const checkRedirectUrl = (_, value, callback) => {
      if (value.length === 0) {
        callback(new Error("跳转连接不能为空"));
        return;
      }
      let reg =
        /^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/;
      if (!reg.test(value)) {
        callback(new Error("请输入正确的地址"));
        return;
      }
      callback();
    };
    // 校验排序值
    const checkCarouselRank = (_, value, callback) => {
      if (value.length === 0) {
        callback(new Error("排序值不能为空"));
        return;
      }
      let reg = /^(\d|([1-9]\d+))$/;
      if (reg.test(value) && value >= 1 && value <= 200) {
        callback();
        return;
      }
      callback(new Error("排序值介于1~200之间"));
    };

    return {
      // 表格相关
      tableData: [],
      tableLoading: false,
      selections: [],
      pagination: {
        pageNumber: 1,
        pageSize: 10,
        total: 0,
      },
      // 表单相关
      visible: false,
      confirmLoading: false,
      ruleForm: {
        carouselId: 0,
        carouselUrl: "",
        redirectUrl: "https://www.baidu.com/",
        carouselRank: 1,
      },
      rules: {
        carouselUrl: [
          { required: true, message: "请先上传图片", trigger: "blur" },
        ],
        redirectUrl: [
          { required: true, validator: checkRedirectUrl, trigger: "blur" },
        ],
        carouselRank: [
          { required: true, validator: checkCarouselRank, trigger: "blur" },
        ],
      },
      headers: {
        token: _.storage.get("tk"),
      },
    };
  },
  methods: {
    // 根据当前页&每页展示条数，从服务器获取轮播图列表
    async init() {
      this.tableLoading = true;
      try {
        let { pageNumber, pageSize } = this.pagination;
        let { resultCode, data } = await this.$api.banner.queryCarouselsList(
          pageNumber,
          pageSize
        );
        if (+resultCode === 200) {
          this.pagination.total = +data.totalCount;
          this.tableData = data.list;
        } else {
          this.pagination.total = 0;
          this.tableData = [];
        }
      } catch (_) {}
      this.tableLoading = false;
    },
    // 表格日期格式化
    formatterTime(row) {
      return _.formatTime(String(row.createTime), "{1}-{2} {3}:{4}");
    },
    // 关闭弹框 & 清空表单信息
    closeDialog() {
      this.visible = false;
      this.confirmLoading = false;
      this.ruleForm = {
        carouselId: 0,
        carouselUrl: "",
        carouselRank: 1,
        redirectUrl: "https://www.baidu.com/",
      };
    },
    // 提交按钮：新增/修改信息
    async submit() {
      try {
        await this.$refs.formIns.validate();
        // 向服务器发送请求
        this.confirmLoading = true;
        let { carouselId, carouselUrl, carouselRank, redirectUrl } =
          this.ruleForm;
        let funcAPI = this.$api.banner.insertCarousels;
        let data = {
          carouselUrl,
          redirectUrl,
          carouselRank,
        };
        if (+carouselId !== 0) {
          // 修改
          data.carouselId = carouselId;
          funcAPI = this.$api.banner.updateCarousels;
        }
        let { resultCode } = await funcAPI(data);
        if (+resultCode === 200) {
          this.$message.success("恭喜您，操作成功！");
          this.closeDialog();
          this.init();
        } else {
          this.$message.error("操作失败，请稍后再试！");
        }
      } catch (_) {}
      this.confirmLoading = false;
    },
    // 文件上传
    uploadSuccess(response) {
      let { resultCode, data } = response;
      if (+resultCode !== 200) {
        this.uploadError();
        return;
      }
      this.ruleForm.carouselUrl = data;
    },
    uploadError() {
      this.$message.error("上传失败，请稍后再试!");
    },
    // 触发修改操作
    async triggerUpdate(row) {
      let { carouselId, carouselUrl, carouselRank, redirectUrl } = row;
      // 先把修改项的ID存储到表单状态中
      this.ruleForm.carouselId = carouselId;
      // 把信息填充到各个表单中{row中包含表单需要的数据，直接赋值即可}
      this.ruleForm.carouselUrl = carouselUrl;
      this.ruleForm.carouselRank = carouselRank;
      this.ruleForm.redirectUrl = redirectUrl;
      this.visible = true;

      /* 
      // 如果row中存储的信息不包含表单需要的内容，则需要从服务器获取
      try {
        let { resultCode, data } = await this.$api.banner.queryCarouselsInfo(
          carouselId
        );
        if (+resultCode === 200) {
          this.ruleForm.carouselUrl = data.carouselUrl;
          this.ruleForm.carouselRank = data.carouselRank;
          this.ruleForm.redirectUrl = data.redirectUrl;
          return;
        }
      } catch (_) {}
      this.$message.error("获取数据失败，目前不能修改!"); 
      */
    },
    // 单一删除 && 批量删除
    async removeHandle(ids) {
      let num = Array.isArray(ids) ? ids.length : 1;
      try {
        let { resultCode } = await this.$api.banner.removeCarousels(ids);
        if (+resultCode === 200) {
          this.$message.success("恭喜您，操作成功!");
          if (this.tableData.length === num && this.pagination.pageNumber > 1) {
            // 如果删除后，这一页没有数据了，应该获取上一页的内容
            this.pagination.pageNumber--;
          }
          this.init();
          return;
        }
        this.$message.error("很遗憾，操作失败!");
      } catch (_) {}
    },
    singleRemove(row) {
      this.removeHandle(row.carouselId);
    },
    async dobuleRemove() {
      if (this.selections.length === 0) {
        this.$message.warning("请至少选择一项进行删除!");
        return;
      }
      this.removeHandle(this.selections);
    },
    // TABLE的全选操作:只要选中项改变则触发
    selectionChange(val) {
      // val:数组,存储选中行的数据
      this.selections = val.map((item) => {
        return item.carouselId;
      });
    },
  },
  created() {
    this.init();
  },
};
</script>

<style lang="less" scoped>
.banner-setting {
  position: relative;
  box-sizing: border-box;
  height: 100%;
  padding: 40px 0;

  .handler-box {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 999;
    display: flex;
    align-items: center;
    box-sizing: border-box;
    width: 100%;
    height: 40px;

    .el-button {
      margin-right: 10px;
    }
  }

  .el-pagination {
    position: absolute;
    bottom: 0;
    right: 0;
    z-index: 999;
    display: flex;
    align-items: center;
    height: 40px;
  }

  .el-table {
    box-sizing: border-box;
    width: 100%;
  }

  .el-image {
    display: block;
    width: 50px;
    height: 50px;
  }

  .el-link {
    margin-right: 10px;
  }

  /deep/.el-dialog__body {
    padding: 10px 20px;
  }

  /deep/.el-upload {
    display: block;
  }

  .avatar-uploader-icon,
  .avatar-uploader-img {
    display: block;
    box-sizing: border-box;
    width: 120px;
    height: 120px;
    line-height: 120px;
    font-size: 24px;
    color: #8c939d;
    border: 1px dashed #d9d9d9;
    cursor: pointer;
  }
}
</style>